package com.rslai.base.tool.servertest.database.datatype;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.dbunit.dataset.ITable;
import org.dbunit.dataset.datatype.AbstractDataType;
import org.dbunit.dataset.datatype.TypeCastException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TimestampDataType extends AbstractDataType {
    public static final TimestampDataType TYPE = new TimestampDataType();

    private static final Logger logger = LoggerFactory.getLogger(TimestampDataType.class);

    private TimestampDataType() {
        super("TIMESTAMP", 93, Timestamp.class, false);
    }

    public Object typeCast(Object value)
            throws TypeCastException {
        logger.debug("typeCast(value={}) - start", value);

        if ((value == null) || (value == ITable.NO_VALUE)) {
            return null;
        }

        if ((value instanceof Timestamp)) {
            return value;
        }

        if ((value instanceof Date)) {
            Date date = (Date) value;
            return new Timestamp(date.getTime());
        }

        if ((value instanceof Long)) {
            Long date = (Long) value;
            return new Timestamp(date.longValue());
        }

        if ((value instanceof String)) {
            String stringValue = (String) value;

            String[] patterns = {"yyyy-MM-dd HH:mm:ss.SSS Z", "yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd HH:mm:ss Z", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm Z", "yyyy-MM-dd HH:mm", "yyyy-MM-dd Z", "yyyy-MM-dd"};

            for (int i = 0; i < patterns.length; i++) {
                String p = patterns[i];
                try {
                    DateFormat df = new SimpleDateFormat(p);
                    Date date = df.parse(stringValue);
                    return new Timestamp(date.getTime());
                } catch (ParseException e) {
                    if (i >= patterns.length) {
                        throw new TypeCastException(value, this, e);
                    }
                }
            }
        }
        throw new TypeCastException(value, this);
    }

    public boolean isDateTime() {
        logger.debug("isDateTime() - start");

        return true;
    }

    public Object getSqlValue(int column, ResultSet resultSet) throws SQLException, TypeCastException {
        if (logger.isDebugEnabled()) {
            logger.debug("getSqlValue(column={}, resultSet={}) - start", new Integer(column), resultSet);
        }
        Timestamp value = resultSet.getTimestamp(column);
        if ((value == null) || (resultSet.wasNull())) {
            return null;
        }
        return value;
    }

    public void setSqlValue(Object value, int column, PreparedStatement statement) throws SQLException, TypeCastException {
        if (logger.isDebugEnabled()) {
            logger.debug("setSqlValue(value={}, column={}, statement={}) - start", new Object[]{value, new Integer(column), statement});
        }

        statement.setTimestamp(column, (Timestamp) typeCast(value));
    }
}
